/**
 * 
 */
package com.isaac.actm.domain.repository.jpa;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;

import com.isaac.actm.domain.pojo.User;
import com.isaac.actm.domain.repository.UserRepository;
import com.isaac.actm.domain.util.PagedQueryResult;

/**
 * @author ybak
 * 
 */
@Transactional
public class JPAUserRepositoryImpl extends JPARepositoryImpl<User>
		implements UserRepository {
	/* (non-Javadoc)
	 * @see com.isaac.actm.domain.repository.UserRepository#findAllUsers()
	 */
	@SuppressWarnings("unchecked")
	@Transactional(readOnly=true)
	public List<User> findAllUsers() {
		List<User> find = jpaTemplate
				.executeFind(new JpaCallback<List<User>>() {
					public List<User> doInJpa(final EntityManager em)
							throws PersistenceException {
						final Query query = em
								.createQuery("select u from User u");
						query.setHint("org.hibernate.cacheable", true);
						return query.getResultList();
					}
				});
		return find;
	}

	@Override
	public void save(User entity) {
		if (entity.getId() == null) {
			entity.setCreateTime(new Date());
		}
		super.save(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.isaac.actm.domain.repository.UserRepository#findUsers(int, int)
	 */
	@Transactional(readOnly=true)
	public PagedQueryResult findUsers(final int startingIndex,
			final int pageSize) {
		PagedQueryResult pagedResult = jpaTemplate
				.execute(new JpaCallback<PagedQueryResult>() {

					@SuppressWarnings("unchecked")
					public PagedQueryResult doInJpa(final EntityManager em)
							throws PersistenceException {
						final Query query = em
								.createQuery("select u from User u");
						query.setFirstResult(startingIndex);
						query.setMaxResults(pageSize + 1);
						final List<User> results = query.getResultList();
						final boolean more = results.size() > pageSize;
						if (more) {
							results.remove(pageSize);
						}
						return new PagedQueryResult(results, more);
					}
				});
		return pagedResult;
	}

}
